package com.zp.base.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zp.base.entity.ClinicForRegist;
import com.zp.base.entity.ClinicIndex;
import com.zp.base.entity.ClinicSchedule;
import com.zp.base.entity.bo.ClinicForRegistBo;
import com.zp.base.entity.vo.ClinicForRegistVo;
import com.zp.base.mapper.ClinicForRegistMapper;
import com.zp.base.mapper.ClinicIndexMapper;
import com.zp.base.mapper.ClinicScheduleMapper;
import com.zp.base.service.IClinicForRegistService;
import com.zp.common.core.utils.DateUtils;
import com.zp.common.core.utils.StringUtils;
import com.zp.common.myBatis.core.page.PageQuery;
import com.zp.common.myBatis.core.page.TableDataInfo;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 号表安排Service业务层处理
 *
 * @author zhang peng
 * @date 2023-01-20
 */
@RequiredArgsConstructor
@Service
public class ClinicForRegistServiceImpl implements IClinicForRegistService {

    private final ClinicForRegistMapper baseMapper;
    private final ClinicIndexMapper clinicIndexMapper;
    private final ClinicScheduleMapper clinicScheduleMapper;

    /**
     * 查询号表安排
     */
    @Override
    public ClinicForRegistVo queryById (String clinicForRegistId) {
        return baseMapper.selectVoById(clinicForRegistId);
    }

    /**
     * 查询号表安排列表(分页)
     */
    @Override
    public TableDataInfo<ClinicForRegistVo> queryPageList (ClinicForRegistBo bo) {
        List<String> clinicScheduleList = new ArrayList<>();
        clinicScheduleList.add("");
        List<ClinicIndex> indexList = clinicIndexMapper.selectList(Wrappers.<ClinicIndex>lambdaQuery()
                .eq(ClinicIndex::getOrgId, bo.getOrgId()));
        LambdaQueryWrapper<ClinicForRegist> lqw = buildQueryWrapper(bo);
        if (CollectionUtil.isNotEmpty(bo.getClinicScheduleList())) {
            clinicScheduleList = bo.getClinicScheduleList().stream().map(ClinicSchedule::getScheduleId).distinct().collect(Collectors.toList());
        }
        lqw.in(ClinicForRegist::getClinicScheduleId, clinicScheduleList);
        lqw.orderByAsc(ClinicForRegist::getClinicIndexId, ClinicForRegist::getClinicDate);
        PageQuery pageQuery = new PageQuery();
        pageQuery.setPageNum(bo.getPageNum());
        pageQuery.setPageSize(bo.getPageSize());
        Page<ClinicForRegistVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        if (CollectionUtil.isNotEmpty(indexList)) {
            result.getRecords().forEach(item -> {
                item.setClinicIndexName(indexList.stream().filter(i -> StringUtils.equals(i.getClinicIndexId(), item.getClinicIndexId())).findAny().get().getName());
            });
        }
        return TableDataInfo.build(result);
    }

    /**
     * 查询号表安排列表(不分页)
     */
    @Override
    public List<ClinicForRegistVo> queryList (ClinicForRegistBo bo) {
        LambdaQueryWrapper<ClinicForRegist> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<ClinicForRegist> buildQueryWrapper (ClinicForRegistBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<ClinicForRegist> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getClinicIndexId()), ClinicForRegist::getClinicIndexId, bo.getClinicIndexId());
        lqw.eq(bo.getClinicDate() != null, ClinicForRegist::getClinicDate, bo.getClinicDate());
        lqw.eq(StringUtils.isNotBlank(bo.getTimeDesc()), ClinicForRegist::getTimeDesc, bo.getTimeDesc());
        lqw.eq(bo.getLimitNum() != null, ClinicForRegist::getLimitNum, bo.getLimitNum());
        lqw.eq(bo.getLimitPreNum() != null, ClinicForRegist::getLimitPreNum, bo.getLimitPreNum());
        lqw.eq(bo.getCurrentNum() != null, ClinicForRegist::getCurrentNum, bo.getCurrentNum());
        lqw.eq(bo.getCurrentRegisNum() != null, ClinicForRegist::getCurrentRegisNum, bo.getCurrentRegisNum());
        lqw.eq(bo.getCurrentPreNum() != null, ClinicForRegist::getCurrentPreNum, bo.getCurrentPreNum());
        lqw.eq(StringUtils.isNotBlank(bo.getOrgId()), ClinicForRegist::getOrgId, bo.getOrgId());
        return lqw;
    }

    /**
     * 新增号表安排
     */
    @Override
    public Boolean insertByBo (ClinicForRegistBo bo) {
        boolean flag = false;
        List<ClinicForRegist> clinicForRegistList = new ArrayList<>();
        // 查询当前机构所有排班信息
        List<ClinicForRegist> clinicForRegistListOld = baseMapper.selectList(
                Wrappers.<ClinicForRegist>lambdaQuery()
                        .eq(ClinicForRegist::getOrgId, bo.getOrgId())
        );
        Map<String, JSONObject> dateMap = DateUtils.getDayListBetweenFromAndToDay(bo.getStartDate(), bo.getStopDate());
        if (CollectionUtil.isNotEmpty(dateMap)) {
            dateMap.forEach((key, value) -> {
//                System.out.println(key + "-------" + value);
                String start = value.getString("start");
                String weeKCode = value.getString("weekCode");
                bo.getClinicScheduleList().forEach(clinicSchedule -> {
                    if (StringUtils.equals(weeKCode, clinicSchedule.getDayOfWeek())) {
                        // 判断前台传入的排班信息数据库是否已存在（出诊安排id && 出诊日期）
                        boolean type = clinicForRegistListOld.stream().anyMatch(m ->
                                m.getClinicScheduleId().equals(clinicSchedule.getScheduleId())
                                        && DateUtils.dateTime(m.getClinicDate()).equals(DateUtils.dateTime(DateUtils.parseDate(start)))
                        );
                        if (!type) {
                            ClinicForRegist clinicForRegist = new ClinicForRegist();
                            clinicForRegist.setClinicScheduleId(clinicSchedule.getScheduleId());
                            clinicForRegist.setClinicIndexId(clinicSchedule.getClinicIndexId());
                            clinicForRegist.setClinicDate(DateUtils.parseDate(start));
                            clinicForRegist.setTimeDesc(clinicSchedule.getTimeDesc());
                            clinicForRegist.setLimitNum(ObjectUtil.isNull(clinicSchedule.getLimitNum()) ? 0L : clinicSchedule.getLimitNum());
                            clinicForRegist.setLimitPreNum(ObjectUtil.isNull(clinicSchedule.getLimitPreNum()) ? 0L : clinicSchedule.getLimitPreNum());
                            clinicForRegist.setCurrentNum(0L);
                            clinicForRegist.setCurrentPreNum(0L);
                            clinicForRegist.setCurrentRegisNum(0L);
                            clinicForRegist.setOrgId(bo.getOrgId());
                            clinicForRegist.setDelFlag("0");
                            clinicForRegistList.add(clinicForRegist);
                        }
                    }
                });
            });
            if (CollectionUtil.isEmpty(clinicForRegistList)) {
                throw new RuntimeException("没有符合的排班信息信息");
            }
//            List<ClinicForRegist> clinicForRegistListNew = clinicForRegistList.stream().filter(
//                    item -> clinicForRegistListOld.stream().allMatch(d -> item.getClinicScheduleId().equals(d.getClinicScheduleId())
//                    )).collect(Collectors.toList());
            flag = baseMapper.insertBatch(clinicForRegistList);
        }
        return flag;
    }

    /**
     * 修改号表安排
     */
    @Override
    public Boolean updateByBo (ClinicForRegistBo bo) {
        ClinicForRegist update = BeanUtil.toBean(bo, ClinicForRegist.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave (ClinicForRegist entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除号表安排
     */
    @Override
    public Boolean deleteWithValidByIds (Collection<String> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }
}
